package net.weitalk.concurrent;

import java.util.concurrent.CountDownLatch;

/**
 * 你可以想象一下这个场景，在车站、机场等出租车时，当很多空出租车就位时，
 * 为防止过度拥挤，调度员指挥排队等待坐车的队伍一次进来 5 个人上车，
 * 等这 5 个人坐车出发，再放进去下一批。
 * 如果用 CountDownLatch 去实现上面的排队场景，该怎么做呢？
 * 假设有 10 个人排队，我们将其分成 5 个人一批，通过 CountDownLatch 来协调批次。
 */

class FirstBatchWorker implements Runnable {
    private CountDownLatch countDownLatch;

    public FirstBatchWorker(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        System.out.println("First batch executed!");
        countDownLatch.countDown();
    }
}

class SecondBatchWorker implements Runnable {
    private CountDownLatch countDownLatch;

    public SecondBatchWorker(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        try {
            countDownLatch.await();
            System.out.println("Second batch executed!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new FirstBatchWorker(countDownLatch));
            t.start();
        }
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new SecondBatchWorker(countDownLatch));
            t.start();
        }
        //not recommended
        while (countDownLatch.getCount() != 1) {
            Thread.sleep(100);
        }
        System.out.println("Wait for first batch to finish!");
        countDownLatch.countDown();
    }
}
